package com.hung.thread.fork_join;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;


public class CountTaskDemo extends RecursiveTask<Integer>
{
    private static final long serialVersionUID = 1L;
    //阈值
    private static final int THRESHOLD = 2;
    private int start;
    private int end;
    
    public CountTaskDemo(int start, int end)
    {
        this.start = start;
        this.end = end;
        System.out.println(Thread.currentThread().getName()+" start = " + start+" end = " + end);
    }

    @Override
    protected Integer compute()
    {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {

        }
        int sum = 0;
        //判断任务是否足够小
        boolean canCompute = (end - start) <= THRESHOLD;
        if(canCompute)
        {
            //如果小于阈值，就进行运算
            for(int i=start; i<=end; i++)
            {
                sum += i;
            }
        }
        else
        {
            //如果大于阈值，就再进行任务拆分
            int middle = (start + end)/2;
            CountTaskDemo leftTask = new CountTaskDemo(start,middle);
            CountTaskDemo rightTask = new CountTaskDemo(middle+1,end);
            //执行子任务
            leftTask.fork();
            rightTask.fork();
            //等待子任务执行完，并得到执行结果
            int leftResult = leftTask.join();
            int rightResult = rightTask.join();
            //合并子任务
            sum = leftResult + rightResult;
            
        }
        return sum;
    }
    
    public static void main(String[] args)
    {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        CountTaskDemo task = new CountTaskDemo(1,11);
        //执行一个任务
        Future<Integer> result = forkJoinPool.submit(task);
        try
        {
            System.out.println(result.get());
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        catch (ExecutionException e)
        {
            e.printStackTrace();
        }
        
    }
    
}